package cxydmmszl.chapter09.t169;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

/**
 * <li style="color: red;">Prob</li>
 * 在有序旋转数组中找到一个数
 * <li style="color: green;">Desc</li>
 * 有序数组 arr 可能经过一次旋转处理，也可能没有，且 arr 可能存在重复的数。
 * 例如，有序数组 [1, 2, 3, 4, 5, 6, 7]，可以旋转处理成 [4, 5, 6,  7, 1, 2, 3] 等。
 * 给定一个可能旋转过的有序数组 arr，在给定一个数 num，返回 arr 中是否含有 num。<br/>
 * <br/>关于旋转操作：可以简单的理解为把序列从某个位置切成两段然后交换位置
 * <br/><br/>[要求]<br/>
 * 期望复杂度为 O(logn)
 * <br/><br/>备注<br/>
 * 1⩽N⩽10^5<br/>
 * 1⩽arr[i]⩽10^9
 * <li style="color: green;">Input</li>
 * 第一行两个整数 N，k。分别表示数组大小，需要查找的数。
 * 接下来一行 N 个数表示数组内的数。
 * <li style="color: green;">Output</li>
 * 若 num 存在于数组中，输出 "Yes"，否则输出 "No"。
 * <li style="color: blue;">Link</li> CD75
 *
 * @author habitplus
 * @since 2021-10-10 16:30
 */
public class Main {
    static final StreamTokenizer st =
            new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

    static int nextInt() {
        try {
            st.nextToken();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return (int) st.nval;
    }

    public static void main(String[] args) {
        int n = nextInt();
        int target = nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = nextInt();
        }

        boolean ans = isContainsInRotateArr(arr, target);

        System.out.println(ans ? "Yes" : "No");
    }

    private static boolean isContainsInRotateArr(int[] arr, int target) {
        if (arr == null || arr.length == 0) return false;

        int l = 0;
        int r = arr.length - 1;
        int mid;
        while (l < r) {
            mid = (l + r) / 2;
            if (arr[mid] == target) return true;

            if (arr[l] == arr[mid] && arr[mid] == arr[r]) {
                // 三点相等，target 可能在 mid 的左侧，也可能在 mid 的右侧
                while (l != mid && arr[l] == arr[mid]) l++;

                if (l == mid) {
                    // mid 的左侧都是和 arr[mid] 相等的值，那 target 就只可能出现在 mid 的右侧
                    l = mid + 1;
                    continue;
                }
            }

            // 以下是 arr[mid] != target 且 arr[l], arr[mid], arr[r] 不都相等
            if (arr[l] != arr[mid]) {
                if (arr[mid] > arr[l]) {
                    // 断点在 mid 的右侧，此时 arr[l,mid] 有序
                    if (target >= arr[l] && target < arr[mid])
                        // target 出现在 arr[l, mid - 1]
                        r = mid - 1;
                    else
                        // target 可能出现在 arr[mid + 1, r]
                        l = mid + 1;
                } else {
                    if (target > arr[mid] && target <= arr[r])
                        l = mid + 1;
                    else
                        r = mid - 1;
                }
            } else {
                if (arr[mid] < arr[r]) {
                    // 断点在 mid 处或 mid 左侧，那么 arr[mid, r] 一定有序
                    if (target > arr[mid] && target <= arr[r])
                        l = mid + 1;
                    else
                        r = mid - 1;
                } else {
                    if (target >= arr[l] && target < arr[mid])
                        r = mid - 1;
                    else
                        l = mid + 1;

                }
            }

        }
        return false;
    }
}
